package com.maidada.codesharebackend.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.maidada.codesharebackend.common.PageResult;
import com.maidada.codesharebackend.common.ThrowUtils;
import com.maidada.codesharebackend.exception.GlobalErrorCode;
import com.maidada.codesharebackend.mapper.UserMapper;
import com.maidada.codesharebackend.model.dto.user.UserAddRequest;
import com.maidada.codesharebackend.model.dto.user.UserLoginRequest;
import com.maidada.codesharebackend.model.dto.user.UserQueryRequest;
import com.maidada.codesharebackend.model.dto.user.UserUpdateRequest;
import com.maidada.codesharebackend.model.entity.User;
import com.maidada.codesharebackend.model.vo.UserVO;
import com.maidada.codesharebackend.service.UserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户表 Service 实现类
 *
 * @author wulinxuan
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Value("${encrypt.user.salt}")
    private String salt;

    @Override
    public UserVO login(UserLoginRequest userLoginRequest) {
        String username = userLoginRequest.getUsername();
        String password = userLoginRequest.getPassword();

        // 查询用户
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, username);
        User user = this.getOne(wrapper);
        ThrowUtils.throwIf(user == null, GlobalErrorCode.PARAMS_ERROR, "账号或密码错误");

        // 校验密码
        String encryptPassword = getEncryptPassword(password);
        ThrowUtils.throwIf(!encryptPassword.equals(user.getPassword()), GlobalErrorCode.PARAMS_ERROR, "账号或密码错误");

        // 校验状态
        ThrowUtils.throwIf(user.getStatus() == 0, GlobalErrorCode.PARAMS_ERROR, "账号已停用");

        // 登录
        StpUtil.login(user.getId());

        // 返回用户信息
        return BeanUtil.copyProperties(user, UserVO.class);
    }

    @Override
    public Boolean logout() {
        // 登出
        StpUtil.logout();
        return true;
    }

    @Override
    public UserVO getCurrentUser(Long userId) {
        ThrowUtils.throwIf(userId == null || userId <= 0, GlobalErrorCode.PARAMS_ERROR, "用户id不能为空");

        User user = this.getById(userId);
        ThrowUtils.throwIf(user == null, GlobalErrorCode.DATA_NOT_FOUND_ERROR, "用户不存在");

        // 校验状态
        ThrowUtils.throwIf(user.getStatus() == 0, GlobalErrorCode.PARAMS_ERROR, "账号已停用");

        return BeanUtil.copyProperties(user, UserVO.class);
    }

    @Override
    public Long addUser(UserAddRequest userAddRequest) {
        String username = userAddRequest.getUsername();

        // 校验账号是否已存在
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, username);
        long count = this.count(wrapper);
        ThrowUtils.throwIf(count > 0, GlobalErrorCode.DATA_ALREADY_EXISTS_ERROR, "账号已存在");

        // 创建用户
        User user = BeanUtil.copyProperties(userAddRequest, User.class);
        // 密码加密
        String encryptPassword = getEncryptPassword(userAddRequest.getPassword());
        user.setPassword(encryptPassword);
        // 设置默认状态
        if (user.getStatus() == null) {
            user.setStatus(1);
        }

        boolean result = this.save(user);
        ThrowUtils.throwIf(!result, GlobalErrorCode.OPERATION_ERROR, "新增用户失败");

        return user.getId();
    }

    @Override
    public Boolean deleteUser(Long id) {
        ThrowUtils.throwIf(id == null || id <= 0, GlobalErrorCode.PARAMS_ERROR, "用户id不能为空");

        // 校验用户是否存在
        User user = this.getById(id);
        ThrowUtils.throwIf(user == null, GlobalErrorCode.DATA_NOT_FOUND_ERROR, "用户不存在");

        boolean result = this.removeById(id);
        ThrowUtils.throwIf(!result, GlobalErrorCode.OPERATION_ERROR, "删除用户失败");

        return true;
    }

    @Override
    public Boolean updateUser(UserUpdateRequest userUpdateRequest) {
        Long id = userUpdateRequest.getId();
        ThrowUtils.throwIf(id == null || id <= 0, GlobalErrorCode.PARAMS_ERROR, "用户id不能为空");

        // 校验用户是否存在
        User user = this.getById(id);
        ThrowUtils.throwIf(user == null, GlobalErrorCode.DATA_NOT_FOUND_ERROR, "用户不存在");

        // 更新用户
        User updateUser = BeanUtil.copyProperties(userUpdateRequest, User.class);
        boolean result = this.updateById(updateUser);
        ThrowUtils.throwIf(!result, GlobalErrorCode.OPERATION_ERROR, "修改用户失败");

        return true;
    }

    @Override
    public PageResult<UserVO> pageUser(UserQueryRequest userQueryRequest) {
        // 构建查询条件
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(userQueryRequest.getId() != null, User::getId, userQueryRequest.getId())
                .like(StrUtil.isNotBlank(userQueryRequest.getUsername()), User::getUsername, userQueryRequest.getUsername())
                .like(StrUtil.isNotBlank(userQueryRequest.getNickname()), User::getNickname, userQueryRequest.getNickname())
                .like(StrUtil.isNotBlank(userQueryRequest.getEmail()), User::getEmail, userQueryRequest.getEmail())
                .eq(userQueryRequest.getSex() != null, User::getSex, userQueryRequest.getSex())
                .eq(userQueryRequest.getRole() != null, User::getRole, userQueryRequest.getRole())
                .eq(userQueryRequest.getStatus() != null, User::getStatus, userQueryRequest.getStatus())
                .orderByDesc(User::getCreateTime);

        // 分页查询
        Page<User> page = new Page<>(userQueryRequest.getPageNo(), userQueryRequest.getPageSize());
        Page<User> userPage = this.page(page, wrapper);

        // 转换为VO
        List<UserVO> userVOList = userPage.getRecords().stream()
                .map(user -> BeanUtil.copyProperties(user, UserVO.class))
                .collect(Collectors.toList());

        return new PageResult<>(userVOList, userPage.getTotal());
    }

    @Override
    public UserVO getUserById(Long id) {
        ThrowUtils.throwIf(id == null || id <= 0, GlobalErrorCode.PARAMS_ERROR, "用户id不能为空");

        User user = this.getById(id);
        ThrowUtils.throwIf(user == null, GlobalErrorCode.DATA_NOT_FOUND_ERROR, "用户不存在");

        return BeanUtil.copyProperties(user, UserVO.class);
    }

    /**
     * 密码加密
     *
     * @param password 密码
     * @return {@link String }
     */
    private String getEncryptPassword(String password) {
        return DigestUtil.md5Hex(password + salt);
    }
}

